﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace ButtonBuilder.Data
{
    public class Repository
    {
        private const string PAGES_FOLDER = "Pages";

        public static string UserDataFolder
        {
            get { return Properties.Settings.Default.UserDataFolder; }
        }

        public static bool HasData
        {
            get
            {
                if (string.IsNullOrWhiteSpace(UserDataFolder) || !Directory.Exists(UserDataFolder))
                {
                    return false;
                }

                if (!Directory.Exists(Path.Combine(UserDataFolder, PAGES_FOLDER)))
                {
                    Directory.CreateDirectory(Path.Combine(UserDataFolder, PAGES_FOLDER));
                }

                return Directory.GetFiles(Path.Combine(UserDataFolder, PAGES_FOLDER), "*.xml")
                    .Length > 0;
            }
        }

        #region Saving Functions
        public static void CreateUserDataFolder(string rootPath)
        {
            string appName = AssemblyUtils.GetAssemblyInfo().Product;
            string targetFolder = Path.Combine(rootPath, appName);

            Directory.CreateDirectory(targetFolder);
            Directory.CreateDirectory(Path.Combine(targetFolder, PAGES_FOLDER));
            
            Properties.Settings.Default.UserDataFolder = targetFolder;
            Properties.Settings.Default.Save();
        }

        public static void DeletePageFile(string pageName)
        {
            try
            {
                File.Delete(Path.Combine(UserDataFolder, PAGES_FOLDER, 
                    GetPageFileName(pageName)));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static string SavePage(Page page)
        {
            return SavePage(page, GetPageFileName(page.Name));
        }

        public static string SavePage(Page page, string fileName)
        {
            try
            {
                string filePath = Path.Combine(UserDataFolder, PAGES_FOLDER, fileName);

                XmlSerializer serializer = new XmlSerializer(typeof(Page));
                TextWriter writer = new StreamWriter(filePath);
                XmlSerializerNamespaces xmlnsEmpty = new XmlSerializerNamespaces();
                xmlnsEmpty.Add("", "");
                serializer.Serialize(writer, page, xmlnsEmpty);
                writer.Close();

                return filePath;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return null;
        }

        private static string GetPageFileName(string pageName)
        {
            string fileName = pageName;

            foreach (var c in Path.GetInvalidFileNameChars())
            {
                fileName = fileName.Replace(c, '_');
            }

            return fileName + ".xml";
        }
        #endregion

        #region Loading Functions
        public static List<Page> LoadPages()
        {
            List<Page> pages = new List<Page>();

            if (!HasData)
                return pages;

            foreach (string file in Directory.GetFiles(Path.Combine(UserDataFolder, PAGES_FOLDER), "*.xml"))
            {
                Page page = LoadPage(file);

                if (page != null)
                    pages.Add(page);
            }
            
            return pages;
        }

        private static Page LoadPage(string fileName)
        {
            Page result = null;

            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Page));
                StreamReader reader = new StreamReader(fileName);
                result = (Page)serializer.Deserialize(reader);
                reader.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return result;
        }
        #endregion
    }
}
